home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / bc-1_02.lha / bc-1.02 / sbc.y < prev    next >
Text File  |  1992-03-04  |  11KB  |  449 lines

  1. , %{
  2. /* sbc.y: A POSIX bc processor written for minix with no extensions.  */
  3.  
  4. /*  This file is part of bc written for MINIX.
  5.     Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  6.  
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License , or
  10.     (at your option) any later version.
  11.  
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.     You may contact the author by:
  22.        e-mail:  phil@cs.wwu.edu
  23.       us-mail:  Philip A. Nelson
  24.                 Computer Science Department, 9062
  25.                 Western Washington University
  26.                 Bellingham, WA 98226-9062
  27.        
  28. *************************************************************************/
  29.  
  30. #include "bcdefs.h"
  31. #include "global.h"     /* To get the global variables. */
  32. #include "proto.h"
  33. %}
  34.  
  35. %start program
  36.  
  37. %union {
  38.     char *s_value;
  39.     char  c_value;
  40.     int   i_value;
  41.     arg_list *a_value;
  42.        }
  43.  
  44. %token <i_value> NEWLINE AND OR NOT
  45. %token <s_value> STRING NAME NUMBER
  46. /*     '-', '+' are tokens themselves        */
  47. %token <c_value> MUL_OP
  48. /*     '*', '/', '%'                 */
  49. %token <c_value> ASSIGN_OP
  50. /*     '=', '+=',  '-=', '*=', '/=', '%=', '^=' */
  51. %token <s_value> REL_OP
  52. /*     '==', '<=', '>=', '!=', '<', '>'     */
  53. %token <c_value> INCR_DECR
  54. /*     '++', '--'                 */
  55. %token <i_value> Define    Break    Quit    Length
  56. /*     'define', 'break', 'quit', 'length'     */
  57. %token <i_value> Return    For    If    While    Sqrt  Else
  58. /*     'return', 'for', 'if', 'while', 'sqrt',  'else'     */
  59. %token <i_value> Scale    Ibase    Obase    Auto  Read
  60. /*     'scale', 'ibase', 'obase', 'auto', 'read'     */
  61. %token <i_value> Warranty, Halt, Last, Continue, Print, Limits
  62. /*     'warranty', 'halt', 'last', 'continue', 'print', 'limits'  */
  63.  
  64. /* The types of all other non-terminals. */
  65. %type <i_value> expression named_expression return_expression
  66. %type <a_value> opt_parameter_list parameter_list opt_auto_define_list
  67. %type <a_value> define_list opt_argument_list argument_list
  68. %type <i_value> program input_item semicolon_list statement_list
  69. %type <i_value> statement_or_error statement function relational_expression 
  70.  
  71. /* precedence */
  72. %nonassoc REL_OP
  73. %right ASSIGN_OP
  74. %left '+' '-'
  75. %left MUL_OP
  76. %right '^'
  77. %nonassoc UNARY_MINUS
  78. %nonassoc INCR_DECR
  79.  
  80. %%
  81. program            : /* empty */
  82.                 {
  83.                   $$ = 0;
  84.                   std_only = TRUE;
  85.                   if (interactive)
  86.                 {
  87.                   printf ("s%s\n", BC_VERSION);
  88.                   welcome();
  89.                 }
  90.                 }
  91.             | program input_item
  92.             ;
  93. input_item        : semicolon_list NEWLINE
  94.                 { run_code(); }
  95.             | function
  96.                 { run_code(); }
  97.             | error NEWLINE
  98.                 {
  99.                   yyerrok; 
  100.                   init_gen() ;
  101.                 }
  102.             ;
  103. semicolon_list        : /* empty */
  104.                 { $$ = 0; }
  105.             | statement_or_error
  106.             | semicolon_list ';' statement_or_error
  107.             | semicolon_list ';'
  108.             ;
  109. statement_list        : /* empty */
  110.                 { $$ = 0; }
  111.             | statement
  112.             | statement_list NEWLINE
  113.             | statement_list NEWLINE statement
  114.             | statement_list ';'
  115.             | statement_list ';' statement
  116.             ;
  117. statement_or_error    : statement
  118.             | error statement
  119.                 { $$ = $2; }
  120.             ;
  121. statement         : Warranty
  122.                 { warranty("s"); }
  123.             | expression
  124.                 {
  125.                   if ($1 & 1)
  126.                 generate ("W");
  127.                   else
  128.                 generate ("p");
  129.                 }
  130.             | STRING
  131.                 {
  132.                   $$ = 0;
  133.                   generate ("w");
  134.                   generate ($1);
  135.                   free ($1);
  136.                 }
  137.             | Break
  138.                 {
  139.                   if (break_label == 0)
  140.                 yyerror ("Break outside a for/while");
  141.                   else
  142.                 {
  143.                   sprintf (genstr, "J%1d:", break_label);
  144.                   generate (genstr);
  145.                 }
  146.                 }
  147.             | Quit
  148.                 { exit(0); }
  149.             | Return
  150.                 { generate ("0R"); }
  151.             | Return '(' return_expression ')'
  152.                 { generate ("R"); }
  153.             | For 
  154.                 {
  155.                   $1 = break_label; 
  156.                   break_label = next_label++;
  157.                 }
  158.               '(' expression ';'
  159.                 {
  160.                   $4 = next_label++;
  161.                   sprintf (genstr, "pN%1d:", $4);
  162.                   generate (genstr);
  163.                 }
  164.               relational_expression ';'
  165.                 {
  166.                   $7 = next_label++;
  167.                   sprintf (genstr, "B%1d:J%1d:", $7, break_label);
  168.                   generate (genstr);
  169.                   $<i_value>$ = next_label++;
  170.                   sprintf (genstr, "N%1d:", $<i_value>$);
  171.                   generate (genstr);
  172.                 }
  173.               expression ')'
  174.                 {
  175.                   sprintf (genstr, "pJ%1d:N%1d:", $4, $7);
  176.                   generate (genstr);
  177.                 }
  178.               statement
  179.                 {
  180.                   sprintf (genstr, "J%1d:N%1d:", $<i_value>9,
  181.                        break_label);
  182.                   generate (genstr);
  183.                   break_label = $1;
  184.                 }
  185.             | If '(' relational_expression ')' 
  186.                 {
  187.                   $3 = next_label++;
  188.                   sprintf (genstr, "Z%1d:", $3);
  189.                   generate (genstr);
  190.                 }
  191.               statement
  192.                 {
  193.                   sprintf (genstr, "N%1d:", $3); 
  194.                   generate (genstr);
  195.                 }
  196.             | While 
  197.                 {
  198.                   $1 = next_label++;
  199.                   sprintf (genstr, "N%1d:", $1);
  200.                   generate (genstr);
  201.                 }
  202.             '(' relational_expression 
  203.                 {
  204.                   $4 = break_label; 
  205.                   break_label = next_label++;
  206.                   sprintf (genstr, "Z%1d:", break_label);
  207.                   generate (genstr);
  208.                 }
  209.             ')' statement
  210.                 {
  211.                   sprintf (genstr, "J%1d:N%1d:", $1, break_label);
  212.                   generate (genstr);
  213.                   break_label = $4;
  214.                 }
  215.             | '{' statement_list '}'
  216.                 { $$ = 0; }
  217.             ;
  218. function         : Define NAME '(' opt_parameter_list ')' '{'
  219.                      NEWLINE opt_auto_define_list 
  220.                 {
  221.                   check_params ($4,$8);
  222.                   sprintf (genstr, "F%d,%s.%s[", lookup($2,FUNCT),
  223.                        arg_str ($4,TRUE), arg_str ($8,TRUE));
  224.                   generate (genstr);
  225.                   free_args ($4);
  226.                   free_args ($8);
  227.                   $1 = next_label;
  228.                   next_label = 0;
  229.                 }
  230.               statement_list NEWLINE '}'
  231.                 {
  232.                   generate ("0R]");
  233.                   next_label = $1;
  234.                 }
  235.             ;
  236. opt_parameter_list    : /* empty */ 
  237.                 { $$ = NULL; }
  238.             | parameter_list
  239.             ;
  240. parameter_list         : NAME
  241.                 { $$ = nextarg (NULL, lookup($1,SIMPLE)); }
  242.             | define_list ',' NAME
  243.                 { $$ = nextarg ($1, lookup($3,SIMPLE)); }
  244.             ;
  245. opt_auto_define_list     : /* empty */ 
  246.                 { $$ = NULL; }
  247.             | Auto define_list NEWLINE
  248.                 { $$ = $2; } 
  249.             | Auto define_list ';'
  250.                 { $$ = $2; } 
  251.             ;
  252. define_list         : NAME
  253.                 { $$ = nextarg (NULL, lookup($1,SIMPLE)); }
  254.             | NAME '[' ']'
  255.                 { $$ = nextarg (NULL, lookup($1,ARRAY)); }
  256.             | define_list ',' NAME
  257.                 { $$ = nextarg ($1, lookup($3,SIMPLE)); }
  258.             | define_list ',' NAME '[' ']'
  259.                 { $$ = nextarg ($1, lookup($3,ARRAY)); }
  260.             ;
  261. opt_argument_list    : /* empty */
  262.                 { $$ = NULL; }
  263.             | argument_list
  264.             ;
  265. argument_list         : expression
  266.                 { $$ = nextarg (NULL,0); }
  267.             | argument_list ',' expression
  268.                 { $$ = nextarg ($1,0); }
  269.             ;
  270. relational_expression    : expression
  271.                 { $$ = 0; }
  272.             | expression REL_OP expression
  273.                 {
  274.                   $$ = 0;
  275.                   switch (*($2))
  276.                 {
  277.                 case '=':
  278.                   generate ("=");
  279.                   break;
  280.                 case '!':
  281.                   generate ("#");
  282.                   break;
  283.                 case '<':
  284.                   if ($2[1] == '=')
  285.                     generate ("{");
  286.                   else
  287.                     generate ("<");
  288.                   break;
  289.                 case '>':
  290.                   if ($2[1] == '=')
  291.                     generate ("}");
  292.                   else
  293.                     generate (">");
  294.                   break;
  295.                 }
  296.                 }
  297.             ;
  298. return_expression    : /* empty */
  299.                 {
  300.                   $$ = 0;
  301.                   generate ("0");
  302.                 }
  303.             | expression
  304.             ;
  305. expression        : named_expression ASSIGN_OP 
  306.                 {
  307.                   if ($2 != '=')
  308.                 {
  309.                   if ($1 < 0)
  310.                     sprintf (genstr, "DL%d:", -$1);
  311.                   else
  312.                     sprintf (genstr, "l%d:", $1);
  313.                   generate (genstr);
  314.                 }
  315.                 }
  316.               expression
  317.                 {
  318.                   $$ = 0;
  319.                   if ($2 != '=')
  320.                 {
  321.                   sprintf (genstr, "%c", $2);
  322.                   generate (genstr);
  323.                 }
  324.                   if ($1 < 0)
  325.                 sprintf (genstr, "S%d:", -$1);
  326.                   else
  327.                 sprintf (genstr, "s%d:", $1);
  328.                   generate (genstr);
  329.                 }
  330.             | expression '+' expression
  331.                 { generate ("+"); }
  332.             | expression '-' expression
  333.                 { generate ("-"); }
  334.             | expression MUL_OP expression
  335.                 {
  336.                   genstr[0] = $2;
  337.                   genstr[1] = 0;
  338.                   generate (genstr);
  339.                 }
  340.             | expression '^' expression
  341.                 { generate ("^"); }
  342.             | '-' expression           %prec UNARY_MINUS
  343.                 { generate ("n"); $$ = 1;}
  344.             | named_expression
  345.                 {
  346.                   $$ = 1;
  347.                   if ($1 < 0)
  348.                 sprintf (genstr, "L%d:", -$1);
  349.                   else
  350.                 sprintf (genstr, "l%d:", $1);
  351.                   generate (genstr);
  352.                 }
  353.             | NUMBER
  354.                 {
  355.                   int len = strlen($1);
  356.                   $$ = 1;
  357.                   if (len == 1 && *$1 == '0')
  358.                 generate ("0");
  359.                   else
  360.                 {
  361.                   if (len == 1 && *$1 == '1')
  362.                     generate ("1");
  363.                   else
  364.                     {
  365.                       generate ("K");
  366.                       generate ($1);
  367.                       generate (":");
  368.                     }
  369.                   free ($1);
  370.                 }
  371.                 }
  372.             | '(' expression ')'
  373.                 { $$ = 1; }
  374.             | NAME '(' opt_argument_list ')'
  375.                 {
  376.                   $$ = 1;
  377.                   if ($3 != NULL)
  378.                 { 
  379.                   sprintf (genstr, "C%d,%s:", lookup($1,FUNCT),
  380.                        arg_str ($3,FALSE));
  381.                   free_args ($3);
  382.                 }
  383.                   else
  384.                   sprintf (genstr, "C%d:", lookup($1,FUNCT));
  385.                   generate (genstr);
  386.                 }
  387.             | INCR_DECR named_expression
  388.                 {
  389.                   $$ = 1;
  390.                   if ($2 < 0)
  391.                 {
  392.                   if ($1 == '+')
  393.                     sprintf (genstr, "DA%d:L%d:", -$2, -$2);
  394.                   else
  395.                     sprintf (genstr, "DM%d:L%d:", -$2, -$2);
  396.                 }
  397.                   else
  398.                 {
  399.                   if ($1 == '+')
  400.                     sprintf (genstr, "i%d:l%d:", $2, $2);
  401.                   else
  402.                     sprintf (genstr, "d%d:l%d:", $2, $2);
  403.                 }
  404.                   generate (genstr);
  405.                 }
  406.             | named_expression INCR_DECR
  407.                 {
  408.                   $$ = 1;
  409.                   if ($1 < 0)
  410.                 {
  411.                   sprintf (genstr, "DL%d:x", -$1);
  412.                   generate (genstr); 
  413.                   if ($2 == '+')
  414.                     sprintf (genstr, "A%d:", -$1);
  415.                   else
  416.                     sprintf (genstr, "M%d:", -$1);
  417.                 }
  418.                   else
  419.                 {
  420.                   sprintf (genstr, "l%d:", $1);
  421.                   generate (genstr);
  422.                   if ($2 == '+')
  423.                     sprintf (genstr, "i%d:", $1);
  424.                   else
  425.                     sprintf (genstr, "d%d:", $1);
  426.                 }
  427.                   generate (genstr);
  428.                 }
  429.             | Length '(' expression ')'
  430.                 { generate ("cL"); $$ = 1;}
  431.             | Sqrt '(' expression ')'
  432.                 { generate ("cR"); $$ = 1;}
  433.             | Scale '(' expression ')'
  434.                 { generate ("cS"); $$ = 1;}
  435.             ;
  436. named_expression    : NAME
  437.                 { $$ = lookup($1,SIMPLE); }
  438.             | NAME '[' expression ']'
  439.                 { $$ = lookup($1,ARRAY); }
  440.             | Ibase
  441.                 { $$ = 0; }
  442.             | Obase
  443.                 { $$ = 1; }
  444.             | Scale
  445.                 { $$ = 2; }
  446.             ;
  447.  
  448. %%
  449.